packages feed

msgpack 0.3.0 → 0.3.1

raw patch · 6 files changed

+399/−285 lines, 6 filesdep +deepseqPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies added: deepseq

API changes (from Hackage documentation)

- Data.MessagePack.Object: instance (OBJECT a) => OBJECT (Maybe a)
- Data.MessagePack.Object: instance (OBJECT a) => OBJECT [a]
- Data.MessagePack.Object: instance (OBJECT a, OBJECT b) => OBJECT [(a, b)]
- Data.MessagePack.Object: instance OBJECT ()
- Data.MessagePack.Object: instance OBJECT Bool
- Data.MessagePack.Object: instance OBJECT ByteString
- Data.MessagePack.Object: instance OBJECT Double
- Data.MessagePack.Object: instance OBJECT Int
- Data.MessagePack.Object: instance OBJECT Object
- Data.MessagePack.Object: instance OBJECT String
- Data.MessagePack.Object: instance Show Object
+ Data.MessagePack: packToHandle' :: Handle -> Put -> IO ()
+ Data.MessagePack: unpackFromFileI :: (MonadCatchIO m) => FilePath -> Iteratee ByteString m a -> m a
+ Data.MessagePack: unpackFromHandleI :: (MonadCatchIO m) => Handle -> Iteratee ByteString m a -> m a
+ Data.MessagePack: unpackFromStringI :: (Monad m, IsByteString s) => s -> Iteratee ByteString m a -> m a
+ Data.MessagePack.Iteratee: enumHandleNonBlocking :: (MonadIO m) => Int -> Handle -> Enumerator ByteString m a
+ Data.MessagePack.Iteratee: getI :: (Monad m, ObjectGet a) => Iteratee ByteString m a
+ Data.MessagePack.Iteratee: parserToIteratee :: (Monad m) => Parser a -> Iteratee ByteString m a
+ Data.MessagePack.Object: instance [overlap ok] (OBJECT a) => OBJECT (Maybe a)
+ Data.MessagePack.Object: instance [overlap ok] (OBJECT a) => OBJECT [a]
+ Data.MessagePack.Object: instance [overlap ok] (OBJECT a, OBJECT b) => OBJECT [(a, b)]
+ Data.MessagePack.Object: instance [overlap ok] Eq Object
+ Data.MessagePack.Object: instance [overlap ok] NFData Object
+ Data.MessagePack.Object: instance [overlap ok] OBJECT ()
+ Data.MessagePack.Object: instance [overlap ok] OBJECT Bool
+ Data.MessagePack.Object: instance [overlap ok] OBJECT ByteString
+ Data.MessagePack.Object: instance [overlap ok] OBJECT Double
+ Data.MessagePack.Object: instance [overlap ok] OBJECT Int
+ Data.MessagePack.Object: instance [overlap ok] OBJECT Object
+ Data.MessagePack.Object: instance [overlap ok] OBJECT String
+ Data.MessagePack.Object: instance [overlap ok] Ord Object
+ Data.MessagePack.Object: instance [overlap ok] Show Object
+ Data.MessagePack.Object: instance [overlap ok] Typeable Object
+ Data.MessagePack.Parser: instance [incoherent] (ObjectGet a1, ObjectGet a2) => ObjectGet (a1, a2)
+ Data.MessagePack.Parser: instance [incoherent] (ObjectGet a1, ObjectGet a2, ObjectGet a3) => ObjectGet (a1, a2, a3)
+ Data.MessagePack.Parser: instance [incoherent] (ObjectGet a1, ObjectGet a2, ObjectGet a3, ObjectGet a4) => ObjectGet (a1, a2, a3, a4)
+ Data.MessagePack.Parser: instance [incoherent] (ObjectGet a1, ObjectGet a2, ObjectGet a3, ObjectGet a4, ObjectGet a5) => ObjectGet (a1, a2, a3, a4, a5)
+ Data.MessagePack.Parser: instance [incoherent] (ObjectGet a1, ObjectGet a2, ObjectGet a3, ObjectGet a4, ObjectGet a5, ObjectGet a6) => ObjectGet (a1, a2, a3, a4, a5, a6)
+ Data.MessagePack.Parser: instance [incoherent] (ObjectGet a1, ObjectGet a2, ObjectGet a3, ObjectGet a4, ObjectGet a5, ObjectGet a6, ObjectGet a7) => ObjectGet (a1, a2, a3, a4, a5, a6, a7)
+ Data.MessagePack.Parser: instance [incoherent] (ObjectGet a1, ObjectGet a2, ObjectGet a3, ObjectGet a4, ObjectGet a5, ObjectGet a6, ObjectGet a7, ObjectGet a8) => ObjectGet (a1, a2, a3, a4, a5, a6, a7, a8)
+ Data.MessagePack.Parser: instance [incoherent] (ObjectGet a1, ObjectGet a2, ObjectGet a3, ObjectGet a4, ObjectGet a5, ObjectGet a6, ObjectGet a7, ObjectGet a8, ObjectGet a9) => ObjectGet (a1, a2, a3, a4, a5, a6, a7, a8, a9)
+ Data.MessagePack.Parser: instance [incoherent] ObjectGet String
+ Data.MessagePack.Put: instance [incoherent] (ObjectPut a1, ObjectPut a2) => ObjectPut (a1, a2)
+ Data.MessagePack.Put: instance [incoherent] (ObjectPut a1, ObjectPut a2, ObjectPut a3) => ObjectPut (a1, a2, a3)
+ Data.MessagePack.Put: instance [incoherent] (ObjectPut a1, ObjectPut a2, ObjectPut a3, ObjectPut a4) => ObjectPut (a1, a2, a3, a4)
+ Data.MessagePack.Put: instance [incoherent] (ObjectPut a1, ObjectPut a2, ObjectPut a3, ObjectPut a4, ObjectPut a5) => ObjectPut (a1, a2, a3, a4, a5)
+ Data.MessagePack.Put: instance [incoherent] (ObjectPut a1, ObjectPut a2, ObjectPut a3, ObjectPut a4, ObjectPut a5, ObjectPut a6) => ObjectPut (a1, a2, a3, a4, a5, a6)
+ Data.MessagePack.Put: instance [incoherent] (ObjectPut a1, ObjectPut a2, ObjectPut a3, ObjectPut a4, ObjectPut a5, ObjectPut a6, ObjectPut a7) => ObjectPut (a1, a2, a3, a4, a5, a6, a7)
+ Data.MessagePack.Put: instance [incoherent] (ObjectPut a1, ObjectPut a2, ObjectPut a3, ObjectPut a4, ObjectPut a5, ObjectPut a6, ObjectPut a7, ObjectPut a8) => ObjectPut (a1, a2, a3, a4, a5, a6, a7, a8)
+ Data.MessagePack.Put: instance [incoherent] (ObjectPut a1, ObjectPut a2, ObjectPut a3, ObjectPut a4, ObjectPut a5, ObjectPut a6, ObjectPut a7, ObjectPut a8, ObjectPut a9) => ObjectPut (a1, a2, a3, a4, a5, a6, a7, a8, a9)
+ Data.MessagePack.Put: instance [incoherent] ObjectPut String

Files

msgpack.cabal view
@@ -1,15 +1,15 @@ Name:               msgpack-Version:            0.3.0+Version:            0.3.1 Synopsis:           A Haskell binding to MessagePack Description:-  A Haskell binding to MessagePack <http://msgpack.sourceforge.jp/>+  A Haskell binding to MessagePack <http://msgpack.org/>  License:            BSD3 License-File:       LICENSE Category:           Data Author:             Hideyuki Tanaka Maintainer:         Hideyuki Tanaka <tanaka.hideyuki@gmail.com>-Homepage:           http://github.com/tanakh/hsmsgpack+Homepage:           http://github.com/msgpack/msgpack Stability:          Experimental Tested-with:        GHC == 6.12.3 Cabal-Version:      >= 1.2@@ -24,7 +24,9 @@                     iteratee >= 0.4 && < 0.5,                     attoparsec >= 0.8.1 && < 0.8.2,                     binary >= 0.5.0 && < 0.5.1,-                    data-binary-ieee754 >= 0.4 && < 0.5+                    data-binary-ieee754 >= 0.4 && < 0.5,+                    deepseq >= 1.1 && <1.2+   Ghc-options:      -Wall -O2   Hs-source-dirs:   src @@ -33,3 +35,4 @@     Data.MessagePack.Object     Data.MessagePack.Put     Data.MessagePack.Parser+    Data.MessagePack.Iteratee
src/Data/MessagePack.hs view
@@ -16,6 +16,7 @@   module Data.MessagePack.Object,   module Data.MessagePack.Put,   module Data.MessagePack.Parser,+  module Data.MessagePack.Iteratee,      -- * Simple functions of Pack and Unpack   pack,@@ -24,12 +25,16 @@   -- * Pack functions   packToString,   packToHandle,+  packToHandle',   packToFile,      -- * Unpack functions   unpackFromString,   unpackFromHandle,   unpackFromFile,+  unpackFromStringI,+  unpackFromHandleI,+  unpackFromFileI,      ) where @@ -41,12 +46,12 @@ import qualified Data.ByteString.Lazy as L import Data.Functor.Identity import qualified Data.Iteratee as I-import qualified Data.Iteratee.IO as I import System.IO  import Data.MessagePack.Object import Data.MessagePack.Put import Data.MessagePack.Parser+import Data.MessagePack.Iteratee  bufferSize :: Int bufferSize = 4 * 1024@@ -67,7 +72,7 @@ -- | Unpack MessagePack string to Haskell data. unpack :: (ObjectGet a, IsByteString s) => s -> a unpack bs =-  runIdentity $ I.run $ I.joinIM $ I.enumPure1Chunk (toBS bs) (parserToIteratee get)+  runIdentity $ I.run $ I.joinIM $ I.enumPure1Chunk (toBS bs) getI  -- TODO: tryUnpack @@ -79,6 +84,10 @@ packToHandle :: Handle -> Put -> IO () packToHandle h = L.hPutStr h . packToString +-- | Pack to Handle and Flush Handle+packToHandle' :: Handle -> Put -> IO ()+packToHandle' h p = packToHandle h p >> hFlush h+ -- | Pack to File packToFile :: FilePath -> Put -> IO () packToFile path = L.writeFile path . packToString@@ -86,32 +95,32 @@ -- | Unpack from ByteString unpackFromString :: (Monad m, IsByteString s) => s -> A.Parser a -> m a unpackFromString bs =-  I.run . I.joinIM . I.enumPure1Chunk (toBS bs) . parserToIteratee+  unpackFromStringI bs . parserToIteratee  -- | Unpack from Handle unpackFromHandle :: CIO.MonadCatchIO m => Handle -> A.Parser a -> m a unpackFromHandle h =-  I.run . I.joinIM . I.enumHandle bufferSize h . parserToIteratee+  unpackFromHandleI h .parserToIteratee  -- | Unpack from File unpackFromFile :: CIO.MonadCatchIO m => FilePath -> A.Parser a -> m a-unpackFromFile path p =+unpackFromFile path =+  unpackFromFileI path . parserToIteratee++-- | Iteratee interface to unpack from ByteString+unpackFromStringI :: (Monad m, IsByteString s) => s -> I.Iteratee B.ByteString m a -> m a+unpackFromStringI bs =+  I.run . I.joinIM . I.enumPure1Chunk (toBS bs)++-- | Iteratee interface to unpack from Handle+unpackFromHandleI :: CIO.MonadCatchIO m => Handle -> I.Iteratee B.ByteString m a -> m a+unpackFromHandleI h =+  I.run . I.joinIM . enumHandleNonBlocking bufferSize h++-- | Iteratee interface to unpack from File+unpackFromFileI :: CIO.MonadCatchIO m => FilePath -> I.Iteratee B.ByteString m a -> m a+unpackFromFileI path p =   CIO.bracket   (liftIO $ openBinaryFile path ReadMode)   (liftIO . hClose)-  (flip unpackFromHandle p)--parserToIteratee :: Monad m => A.Parser a -> I.Iteratee B.ByteString m a-parserToIteratee p = I.icont (itr (A.parse p)) Nothing-  where-    itr pcont s = case s of-      I.EOF _ ->-        I.throwErr (I.setEOF s)-      I.Chunk bs ->-        case pcont bs of-          A.Fail _ _ msg ->-            I.throwErr (I.iterStrExc msg)-          A.Partial cont ->-            I.icont (itr cont) Nothing-          A.Done remain ret ->-            I.idone ret (I.Chunk remain)+  (flip unpackFromHandleI p)
+ src/Data/MessagePack/Iteratee.hs view
@@ -0,0 +1,82 @@+--------------------------------------------------------------------+-- |+-- Module    : Data.MessagePack.Iteratee+-- Copyright : (c) Hideyuki Tanaka, 2009-2010+-- License   : BSD3+--+-- Maintainer:  tanaka.hideyuki@gmail.com+-- Stability :  experimental+-- Portability: portable+--+-- MessagePack Deserializer interface to @Data.Iteratee@+--+--------------------------------------------------------------------++module Data.MessagePack.Iteratee(+  -- * Iteratee version of deserializer+  getI,+  -- * Non Blocking Enumerator+  enumHandleNonBlocking,+  -- * Convert Parser to Iteratee+  parserToIteratee,+  ) where++import Control.Exception+import Control.Monad.IO.Class+import qualified Data.Attoparsec as A+import qualified Data.ByteString as B+import qualified Data.Iteratee as I+import System.IO++import Data.MessagePack.Parser++-- | Deserialize a value+getI :: (Monad m, ObjectGet a) => I.Iteratee B.ByteString m a+getI = parserToIteratee get++-- | Enumerator+enumHandleNonBlocking :: MonadIO m => Int -> Handle -> I.Enumerator B.ByteString m a+enumHandleNonBlocking bufSize h =+  I.enumFromCallback $ readSome bufSize h++readSome :: MonadIO m => Int -> Handle -> m (Either SomeException (Bool, B.ByteString))+readSome bufSize h = liftIO $ do+  ebs <- try $ hGetSome bufSize h+  case ebs of+    Left exc ->+      return $ Left (exc :: SomeException)+    Right bs | B.null bs ->+      return $ Right (False, B.empty)+    Right bs ->+      return $ Right (True, bs)++hGetSome :: Int -> Handle -> IO B.ByteString+hGetSome bufSize h = do+  bs <- B.hGetNonBlocking h bufSize+  if B.null bs+    then do+    hd <- B.hGet h 1+    if B.null hd+      then do+      return B.empty+      else do+      rest <- B.hGetNonBlocking h (bufSize - 1)+      return $ B.cons (B.head hd) rest+    else do+    return bs++-- | Convert Parser to Iteratee+parserToIteratee :: Monad m => A.Parser a -> I.Iteratee B.ByteString m a+parserToIteratee p = I.icont (itr (A.parse p)) Nothing+  where+    itr pcont s = case s of+      I.EOF _ ->+        I.throwErr (I.setEOF s)+      I.Chunk bs ->+        case pcont bs of+          A.Fail _ _ msg ->+            I.throwErr (I.iterStrExc msg)+          A.Partial cont ->+            I.icont (itr cont) Nothing+          A.Done remain ret ->+            I.idone ret (I.Chunk remain)
src/Data/MessagePack/Object.hs view
@@ -1,5 +1,7 @@-{-# LANGUAGE TypeSynonymInstances #-}-{-# LANGUAGE FlexibleInstances #-}+{-# Language TypeSynonymInstances #-}+{-# Language FlexibleInstances #-}+{-# Language OverlappingInstances #-}+{-# Language DeriveDataTypeable #-}  -------------------------------------------------------------------- -- |@@ -24,10 +26,12 @@   Result,   ) where +import Control.DeepSeq import Control.Monad import Control.Monad.Trans.Error () import qualified Data.ByteString as B import qualified Data.ByteString.Char8 as C8+import Data.Typeable  -- | Object Representation of MessagePack data. data Object =@@ -38,7 +42,18 @@   | ObjectRAW B.ByteString   | ObjectArray [Object]   | ObjectMap [(Object, Object)]-  deriving (Show)+  deriving (Show, Eq, Ord, Typeable)++instance NFData Object where+  rnf obj =+    case obj of+      ObjectNil -> ()+      ObjectBool b -> rnf b+      ObjectInteger n -> rnf n+      ObjectDouble d -> rnf d+      ObjectRAW bs -> bs `seq` ()+      ObjectArray a -> rnf a+      ObjectMap m -> rnf m  -- | The class of types serializable to and from MessagePack object class OBJECT a where
src/Data/MessagePack/Parser.hs view
@@ -1,6 +1,7 @@ {-# Language FlexibleInstances #-} {-# Language IncoherentInstances #-} {-# Language OverlappingInstances #-}+{-# Language TypeSynonymInstances #-}  -------------------------------------------------------------------- -- |@@ -27,6 +28,7 @@ import Data.Binary.IEEE754 import Data.Bits import qualified Data.ByteString as B+import qualified Data.ByteString.Char8 as B8 import qualified Data.ByteString.Lazy as L import Data.Int import qualified Data.Vector as V@@ -40,172 +42,181 @@   -- | Deserialize a value   get :: A.Parser a +instance ObjectGet Object where+  get =+    A.choice+    [ liftM ObjectInteger get+    , liftM (\() -> ObjectNil) get+    , liftM ObjectBool get+    , liftM ObjectDouble get+    , liftM ObjectRAW get+    , liftM ObjectArray get+    , liftM ObjectMap get+    ]+ instance ObjectGet Int where-  get = parseInt+  get = do+    c <- A.anyWord8+    case c of+      _ | c .&. 0x80 == 0x00 ->+        return $ fromIntegral c+      _ | c .&. 0xE0 == 0xE0 ->+        return $ fromIntegral (fromIntegral c :: Int8)+      0xCC ->+        return . fromIntegral =<< A.anyWord8+      0xCD ->+        return . fromIntegral =<< parseUint16+      0xCE ->+        return . fromIntegral =<< parseUint32+      0xCF ->+        return . fromIntegral =<< parseUint64+      0xD0 ->+        return . fromIntegral =<< parseInt8+      0xD1 ->+        return . fromIntegral =<< parseInt16+      0xD2 ->+        return . fromIntegral =<< parseInt32+      0xD3 ->+        return . fromIntegral =<< parseInt64+      _ ->+        fail $ printf "invlid integer tag: 0x%02X" c  instance ObjectGet () where-  get = parseNil+  get = do+    c <- A.anyWord8+    case c of+      0xC0 ->+        return ()+      _ ->+        fail $ printf "invlid nil tag: 0x%02X" c  instance ObjectGet Bool where-  get = parseBool+  get = do+    c <- A.anyWord8+    case c of+      0xC3 ->+        return True+      0xC2 ->+        return False+      _ ->+        fail $ printf "invlid bool tag: 0x%02X" c  instance ObjectGet Double where-  get = parseDouble+  get = do+    c <- A.anyWord8+    case c of+      0xCA ->+        return . realToFrac . runGet getFloat32be . toLBS =<< A.take 4+      0xCB ->+        return . runGet getFloat64be . toLBS =<< A.take 8+      _ ->+        fail $ printf "invlid double tag: 0x%02X" c +instance ObjectGet String where+  get = parseString (\n -> return . B8.unpack =<< A.take n)+ instance ObjectGet B.ByteString where-  get = parseRAW+  get = parseString A.take +instance ObjectGet L.ByteString where+  get = parseString (\n -> do bs <- A.take n; return $ L.fromChunks [bs])++parseString :: (Int -> A.Parser a) -> A.Parser a+parseString aget = do+  c <- A.anyWord8+  case c of+    _ | c .&. 0xE0 == 0xA0 ->+      aget . fromIntegral $ c .&. 0x1F+    0xDA ->+      aget . fromIntegral =<< parseUint16+    0xDB ->+      aget . fromIntegral =<< parseUint32+    _ ->+      fail $ printf "invlid raw tag: 0x%02X" c+ instance ObjectGet a => ObjectGet [a] where-  get = parseArray+  get = parseArray (flip replicateM get)  instance ObjectGet a => ObjectGet (V.Vector a) where-  get = parseArrayVector+  get = parseArray (flip V.replicateM get) -instance (ObjectGet k, ObjectGet v) => ObjectGet [(k, v)] where-  get = parseMap+instance (ObjectGet a1, ObjectGet a2) => ObjectGet (a1, a2) where+  get = parseArray f where+    f 2 = get >>= \a1 -> get >>= \a2 -> return (a1, a2)+    f n = fail $ printf "wrong tupple size: expected 2 but got " n -instance (ObjectGet k, ObjectGet v) => ObjectGet (V.Vector (k, v)) where-  get = parseMapVector+instance (ObjectGet a1, ObjectGet a2, ObjectGet a3) => ObjectGet (a1, a2, a3) where+  get = parseArray f where+    f 3 = get >>= \a1 -> get >>= \a2 -> get >>= \a3 -> return (a1, a2, a3)+    f n = fail $ printf "wrong tupple size: expected 3 but got " n -instance ObjectGet Object where-  get = parseObject+instance (ObjectGet a1, ObjectGet a2, ObjectGet a3, ObjectGet a4) => ObjectGet (a1, a2, a3, a4) where+  get = parseArray f where+    f 4 = get >>= \a1 -> get >>= \a2 -> get >>= \a3 -> get >>= \a4 -> return (a1, a2, a3, a4)+    f n = fail $ printf "wrong tupple size: expected 4 but got " n -parseInt :: A.Parser Int-parseInt = do-  c <- A.anyWord8-  case c of-    _ | c .&. 0x80 == 0x00 ->-      return $ fromIntegral c-    _ | c .&. 0xE0 == 0xE0 ->-      return $ fromIntegral (fromIntegral c :: Int8)      -    0xCC ->-      return . fromIntegral =<< A.anyWord8-    0xCD ->-      return . fromIntegral =<< parseUint16-    0xCE ->-      return . fromIntegral =<< parseUint32-    0xCF ->-      return . fromIntegral =<< parseUint64-    0xD0 ->-      return . fromIntegral =<< parseInt8-    0xD1 ->-      return . fromIntegral =<< parseInt16-    0xD2 ->-      return . fromIntegral =<< parseInt32-    0xD3 ->-      return . fromIntegral =<< parseInt64-    _ ->-      fail $ printf "invlid integer tag: 0x%02X" c+instance (ObjectGet a1, ObjectGet a2, ObjectGet a3, ObjectGet a4, ObjectGet a5) => ObjectGet (a1, a2, a3, a4, a5) where+  get = parseArray f where+    f 5 = get >>= \a1 -> get >>= \a2 -> get >>= \a3 -> get >>= \a4 -> get >>= \a5 -> return (a1, a2, a3, a4, a5)+    f n = fail $ printf "wrong tupple size: expected 5 but got " n -parseNil :: A.Parser ()-parseNil = do-  _ <- A.word8 0xC0-  return ()+instance (ObjectGet a1, ObjectGet a2, ObjectGet a3, ObjectGet a4, ObjectGet a5, ObjectGet a6) => ObjectGet (a1, a2, a3, a4, a5, a6) where+  get = parseArray f where+    f 6 = get >>= \a1 -> get >>= \a2 -> get >>= \a3 -> get >>= \a4 -> get >>= \a5 -> get >>= \a6 -> return (a1, a2, a3, a4, a5, a6)+    f n = fail $ printf "wrong tupple size: expected 6 but got " n -parseBool :: A.Parser Bool-parseBool = do-  c <- A.anyWord8-  case c of-    0xC3 ->-      return True-    0xC2 ->-      return False-    _ ->-      fail $ printf "invlid bool tag: 0x%02X" c+instance (ObjectGet a1, ObjectGet a2, ObjectGet a3, ObjectGet a4, ObjectGet a5, ObjectGet a6, ObjectGet a7) => ObjectGet (a1, a2, a3, a4, a5, a6, a7) where+  get = parseArray f where+    f 7 = get >>= \a1 -> get >>= \a2 -> get >>= \a3 -> get >>= \a4 -> get >>= \a5 -> get >>= \a6 -> get >>= \a7 -> return (a1, a2, a3, a4, a5, a6, a7)+    f n = fail $ printf "wrong tupple size: expected 7 but got " n -parseDouble :: A.Parser Double-parseDouble = do-  c <- A.anyWord8-  case c of-    0xCA ->-      return . realToFrac . runGet getFloat32be . toLBS =<< A.take 4-    0xCB ->-      return . runGet getFloat64be . toLBS =<< A.take 8-    _ ->-      fail $ printf "invlid double tag: 0x%02X" c+instance (ObjectGet a1, ObjectGet a2, ObjectGet a3, ObjectGet a4, ObjectGet a5, ObjectGet a6, ObjectGet a7, ObjectGet a8) => ObjectGet (a1, a2, a3, a4, a5, a6, a7, a8) where+  get = parseArray f where+    f 8 = get >>= \a1 -> get >>= \a2 -> get >>= \a3 -> get >>= \a4 -> get >>= \a5 -> get >>= \a6 -> get >>= \a7 -> get >>= \a8 -> return (a1, a2, a3, a4, a5, a6, a7, a8)+    f n = fail $ printf "wrong tupple size: expected 8 but got " n -parseRAW :: A.Parser B.ByteString-parseRAW = do-  c <- A.anyWord8-  case c of-    _ | c .&. 0xE0 == 0xA0 ->-      A.take . fromIntegral $ c .&. 0x1F-    0xDA ->-      A.take . fromIntegral =<< parseUint16-    0xDB ->-      A.take . fromIntegral =<< parseUint32-    _ ->-      fail $ printf "invlid raw tag: 0x%02X" c-  -parseArray :: ObjectGet a => A.Parser [a]-parseArray = do-  c <- A.anyWord8-  case c of-    _ | c .&. 0xF0 == 0x90 ->-      flip replicateM get . fromIntegral $ c .&. 0x0F-    0xDC ->-      flip replicateM get . fromIntegral =<< parseUint16-    0xDD ->-      flip replicateM get . fromIntegral =<< parseUint32-    _ ->-      fail $ printf "invlid array tag: 0x%02X" c+instance (ObjectGet a1, ObjectGet a2, ObjectGet a3, ObjectGet a4, ObjectGet a5, ObjectGet a6, ObjectGet a7, ObjectGet a8, ObjectGet a9) => ObjectGet (a1, a2, a3, a4, a5, a6, a7, a8, a9) where+  get = parseArray f where+    f 9 = get >>= \a1 -> get >>= \a2 -> get >>= \a3 -> get >>= \a4 -> get >>= \a5 -> get >>= \a6 -> get >>= \a7 -> get >>= \a8 -> get >>= \a9 -> return (a1, a2, a3, a4, a5, a6, a7, a8, a9)+    f n = fail $ printf "wrong tupple size: expected 9 but got " n -parseArrayVector :: ObjectGet a => A.Parser (V.Vector a)-parseArrayVector = do+parseArray :: (Int -> A.Parser a) -> A.Parser a+parseArray aget = do   c <- A.anyWord8   case c of     _ | c .&. 0xF0 == 0x90 ->-      flip V.replicateM get . fromIntegral $ c .&. 0x0F+      aget . fromIntegral $ c .&. 0x0F     0xDC ->-      flip V.replicateM get . fromIntegral =<< parseUint16+      aget . fromIntegral =<< parseUint16     0xDD ->-      flip V.replicateM get . fromIntegral =<< parseUint32+      aget . fromIntegral =<< parseUint32     _ ->       fail $ printf "invlid array tag: 0x%02X" c -parseMap :: (ObjectGet k, ObjectGet v) => A.Parser [(k, v)]-parseMap = do-  c <- A.anyWord8-  case c of-    _ | c .&. 0xF0 == 0x80 ->-      flip replicateM parsePair . fromIntegral $ c .&. 0x0F-    0xDE ->-      flip replicateM parsePair . fromIntegral =<< parseUint16-    0xDF ->-      flip replicateM parsePair . fromIntegral =<< parseUint32-    _ ->-      fail $ printf "invlid map tag: 0x%02X" c+instance (ObjectGet k, ObjectGet v) => ObjectGet [(k, v)] where+  get = parseMap (flip replicateM parsePair) -parseMapVector :: (ObjectGet k, ObjectGet v) => A.Parser (V.Vector (k, v))-parseMapVector = do+instance (ObjectGet k, ObjectGet v) => ObjectGet (V.Vector (k, v)) where+  get = parseMap (flip V.replicateM parsePair)++parsePair :: (ObjectGet k, ObjectGet v) => A.Parser (k, v)+parsePair = do+  a <- get+  b <- get+  return (a, b)++parseMap :: (Int -> A.Parser a) -> A.Parser a+parseMap aget = do   c <- A.anyWord8   case c of     _ | c .&. 0xF0 == 0x80 ->-      flip V.replicateM parsePair . fromIntegral $ c .&. 0x0F+      aget . fromIntegral $ c .&. 0x0F     0xDE ->-      flip V.replicateM parsePair . fromIntegral =<< parseUint16+      aget . fromIntegral =<< parseUint16     0xDF ->-      flip V.replicateM parsePair . fromIntegral =<< parseUint32+      aget . fromIntegral =<< parseUint32     _ ->       fail $ printf "invlid map tag: 0x%02X" c--parseObject :: A.Parser Object-parseObject =-  A.choice-  [ liftM ObjectInteger parseInt-  , liftM (const ObjectNil) parseNil-  , liftM ObjectBool parseBool-  , liftM ObjectDouble parseDouble-  , liftM ObjectRAW parseRAW-  , liftM ObjectArray parseArray-  , liftM ObjectMap parseMap-  ]--parsePair :: (ObjectGet k, ObjectGet v) => A.Parser (k, v)-parsePair = do-  a <- get-  b <- get-  return (a, b)  parseUint16 :: A.Parser Word16 parseUint16 = do
src/Data/MessagePack/Put.hs view
@@ -1,6 +1,7 @@ {-# Language FlexibleInstances #-} {-# Language IncoherentInstances #-} {-# Language OverlappingInstances #-}+{-# Language TypeSynonymInstances #-}  -------------------------------------------------------------------- -- |@@ -25,6 +26,8 @@ import Data.Binary.IEEE754 import Data.Bits import qualified Data.ByteString as B+import qualified Data.ByteString.Char8 as B8+import qualified Data.ByteString.Lazy as L import qualified Data.Vector as V  import Data.MessagePack.Object@@ -35,168 +38,159 @@   put :: a -> Put  instance ObjectPut Object where-  put = putObject+  put obj =+    case obj of+      ObjectInteger n ->+        put n+      ObjectNil ->+        put ()+      ObjectBool b ->+        put b+      ObjectDouble d ->+        put d+      ObjectRAW raw ->+        put raw+      ObjectArray arr ->+        put arr+      ObjectMap m ->+        put m  instance ObjectPut Int where-  put = putInteger+  put n =+    case n of+      _ | n >= 0 && n <= 127 ->+        putWord8 $ fromIntegral n+      _ | n >= -32 && n <= -1 ->+        putWord8 $ fromIntegral n+      _ | n >= 0 && n < 0x100 -> do+        putWord8 0xCC+        putWord8 $ fromIntegral n+      _ | n >= 0 && n < 0x10000 -> do+        putWord8 0xCD+        putWord16be $ fromIntegral n+      _ | n >= 0 && n < 0x100000000 -> do+        putWord8 0xCE+        putWord32be $ fromIntegral n+      _ | n >= 0 -> do+        putWord8 0xCF+        putWord64be $ fromIntegral n+      _ | n >= -0x80 -> do+        putWord8 0xD0+        putWord8 $ fromIntegral n+      _ | n >= -0x8000 -> do+        putWord8 0xD1+        putWord16be $ fromIntegral n+      _ | n >= -0x80000000 -> do+        putWord8 0xD2+        putWord32be $ fromIntegral n+      _ -> do+        putWord8 0xD3+        putWord64be $ fromIntegral n  instance ObjectPut () where-  put _ = putNil+  put _ = +    putWord8 0xC0  instance ObjectPut Bool where-  put = putBool+  put True = putWord8 0xC3+  put False = putWord8 0xC2  instance ObjectPut Double where-  put = putDouble+  put d = do+    putWord8 0xCB+    putFloat64be d +instance ObjectPut String where+  put = putString length (putByteString . B8.pack)+ instance ObjectPut B.ByteString where-  put = putRAW+  put = putString B.length putByteString +instance ObjectPut L.ByteString where+  put = putString (fromIntegral . L.length) putLazyByteString++putString :: (s -> Int) -> (s -> Put) -> s -> Put+putString lf pf str = do+  case lf str of+    len | len <= 31 -> do+      putWord8 $ 0xA0 .|. fromIntegral len+    len | len < 0x10000 -> do+      putWord8 0xDA+      putWord16be $ fromIntegral len+    len -> do+      putWord8 0xDB+      putWord32be $ fromIntegral len+  pf str+ instance ObjectPut a => ObjectPut [a] where-  put = putArray+  put = putArray length (mapM_ put)  instance ObjectPut a => ObjectPut (V.Vector a) where-  put = putArrayVector+  put = putArray V.length (V.mapM_ put) -instance (ObjectPut k, ObjectPut v) => ObjectPut [(k, v)] where-  put = putMap+instance (ObjectPut a1, ObjectPut a2) => ObjectPut (a1, a2) where+  put = putArray (const 2) f where+    f (a1, a2) = put a1 >> put a2 -instance (ObjectPut k, ObjectPut v) => ObjectPut (V.Vector (k, v)) where-  put = putMapVector+instance (ObjectPut a1, ObjectPut a2, ObjectPut a3) => ObjectPut (a1, a2, a3) where+  put = putArray (const 3) f where+    f (a1, a2, a3) = put a1 >> put a2 >> put a3 -putObject :: Object -> Put-putObject obj =-  case obj of-    ObjectInteger n ->-      putInteger n-    ObjectNil ->-      putNil-    ObjectBool b ->-      putBool b-    ObjectDouble d ->-      putDouble d-    ObjectRAW raw ->-      putRAW raw-    ObjectArray arr ->-      putArray arr-    ObjectMap m ->-      putMap m+instance (ObjectPut a1, ObjectPut a2, ObjectPut a3, ObjectPut a4) => ObjectPut (a1, a2, a3, a4) where+  put = putArray (const 4) f where+    f (a1, a2, a3, a4) = put a1 >> put a2 >> put a3 >> put a4 -putInteger :: Int -> Put      -putInteger n =-  case n of-    _ | n >= 0 && n <= 127 ->-      putWord8 $ fromIntegral n-    _ | n >= -32 && n <= -1 ->-      putWord8 $ fromIntegral n-    _ | n >= 0 && n < 0x100 -> do-      putWord8 0xCC-      putWord8 $ fromIntegral n-    _ | n >= 0 && n < 0x10000 -> do-      putWord8 0xCD-      putWord16be $ fromIntegral n-    _ | n >= 0 && n < 0x100000000 -> do-      putWord8 0xCE-      putWord32be $ fromIntegral n-    _ | n >= 0 -> do-      putWord8 0xCF-      putWord64be $ fromIntegral n-    _ | n >= -0x80 -> do-      putWord8 0xD0-      putWord8 $ fromIntegral n-    _ | n >= -0x8000 -> do-      putWord8 0xD1-      putWord16be $ fromIntegral n-    _ | n >= -0x80000000 -> do-      putWord8 0xD2-      putWord32be $ fromIntegral n-    _ -> do-      putWord8 0xD3-      putWord64be $ fromIntegral n+instance (ObjectPut a1, ObjectPut a2, ObjectPut a3, ObjectPut a4, ObjectPut a5) => ObjectPut (a1, a2, a3, a4, a5) where+  put = putArray (const 5) f where+    f (a1, a2, a3, a4, a5) = put a1 >> put a2 >> put a3 >> put a4 >> put a5 -putNil :: Put-putNil = putWord8 0xC0+instance (ObjectPut a1, ObjectPut a2, ObjectPut a3, ObjectPut a4, ObjectPut a5, ObjectPut a6) => ObjectPut (a1, a2, a3, a4, a5, a6) where+  put = putArray (const 6) f where+    f (a1, a2, a3, a4, a5, a6) = put a1 >> put a2 >> put a3 >> put a4 >> put a5 >> put a6 -putBool :: Bool -> Put-putBool True = putWord8 0xC3-putBool False = putWord8 0xC2+instance (ObjectPut a1, ObjectPut a2, ObjectPut a3, ObjectPut a4, ObjectPut a5, ObjectPut a6, ObjectPut a7) => ObjectPut (a1, a2, a3, a4, a5, a6, a7) where+  put = putArray (const 7) f where+    f (a1, a2, a3, a4, a5, a6, a7) = put a1 >> put a2 >> put a3 >> put a4 >> put a5 >> put a6 >> put a7 -putDouble :: Double -> Put-putDouble d = do-  putWord8 0xCB-  putFloat64be d+instance (ObjectPut a1, ObjectPut a2, ObjectPut a3, ObjectPut a4, ObjectPut a5, ObjectPut a6, ObjectPut a7, ObjectPut a8) => ObjectPut (a1, a2, a3, a4, a5, a6, a7, a8) where+  put = putArray (const 8) f where+    f (a1, a2, a3, a4, a5, a6, a7, a8) = put a1 >> put a2 >> put a3 >> put a4 >> put a5 >> put a6 >> put a7 >> put a8 -putRAW :: B.ByteString -> Put-putRAW bs = do-  case len of-    _ | len <= 31 -> do-      putWord8 $ 0xA0 .|. fromIntegral len-    _ | len < 0x10000 -> do-      putWord8 0xDA-      putWord16be $ fromIntegral len-    _ -> do-      putWord8 0xDB-      putWord32be $ fromIntegral len-  putByteString bs-  where-    len = B.length bs+instance (ObjectPut a1, ObjectPut a2, ObjectPut a3, ObjectPut a4, ObjectPut a5, ObjectPut a6, ObjectPut a7, ObjectPut a8, ObjectPut a9) => ObjectPut (a1, a2, a3, a4, a5, a6, a7, a8, a9) where+  put = putArray (const 9) f where+    f (a1, a2, a3, a4, a5, a6, a7, a8, a9) = put a1 >> put a2 >> put a3 >> put a4 >> put a5 >> put a6 >> put a7 >> put a8 >> put a9 -putArray :: ObjectPut a => [a] -> Put-putArray arr = do-  case len of-    _ | len <= 15 ->+putArray :: (a -> Int) -> (a -> Put) -> a -> Put+putArray lf pf arr = do+  case lf arr of+    len | len <= 15 ->       putWord8 $ 0x90 .|. fromIntegral len-    _ | len < 0x10000 -> do+    len | len < 0x10000 -> do       putWord8 0xDC       putWord16be $ fromIntegral len-    _ -> do+    len -> do       putWord8 0xDD       putWord32be $ fromIntegral len-  mapM_ put arr-  where-    len = length arr+  pf arr -putArrayVector :: ObjectPut a => V.Vector a -> Put-putArrayVector arr = do-  case len of-    _ | len <= 15 ->-      putWord8 $ 0x90 .|. fromIntegral len-    _ | len < 0x10000 -> do-      putWord8 0xDC-      putWord16be $ fromIntegral len-    _ -> do-      putWord8 0xDD-      putWord32be $ fromIntegral len-  V.mapM_ put arr-  where-    len = V.length arr+instance (ObjectPut k, ObjectPut v) => ObjectPut [(k, v)] where+  put = putMap length (mapM_ putPair) -putMap :: (ObjectPut k, ObjectPut v) => [(k, v)] -> Put-putMap m = do-  case len of-    _ | len <= 15 ->-      putWord8 $ 0x80 .|. fromIntegral len-    _ | len < 0x10000 -> do-      putWord8 0xDE-      putWord16be $ fromIntegral len-    _ -> do-      putWord8 0xDF-      putWord32be $ fromIntegral len-  mapM_ (\(k, v) -> put k >> put v) m-  where-    len = length m+instance (ObjectPut k, ObjectPut v) => ObjectPut (V.Vector (k, v)) where+  put = putMap V.length (V.mapM_ putPair) -putMapVector :: (ObjectPut k, ObjectPut v) => V.Vector (k, v) -> Put-putMapVector m = do-  case len of-    _ | len <= 15 ->+putPair :: (ObjectPut a, ObjectPut b) => (a, b) -> Put+putPair (a, b) = put a >> put b++putMap :: (a -> Int) -> (a -> Put) -> a -> Put+putMap lf pf m = do+  case lf m of+    len | len <= 15 ->       putWord8 $ 0x80 .|. fromIntegral len-    _ | len < 0x10000 -> do+    len | len < 0x10000 -> do       putWord8 0xDE       putWord16be $ fromIntegral len-    _ -> do+    len -> do       putWord8 0xDF       putWord32be $ fromIntegral len-  V.mapM_ (\(k, v) -> put k >> put v) m-  where-    len = V.length m+  pf m