packages feed

bert 1.2.2.4 → 1.2.2.5

raw patch · 4 files changed

+103/−6 lines, 4 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Data.BERT.Packet: instance Binary Packet
- Data.BERT.Packet: instance Eq Packet
- Data.BERT.Packet: instance Ord Packet
- Data.BERT.Packet: instance Show Packet
- Data.BERT.Term: instance [overlap ok] (BERT a, BERT b) => BERT (a, b)
- Data.BERT.Term: instance [overlap ok] (BERT a, BERT b, BERT c) => BERT (a, b, c)
- Data.BERT.Term: instance [overlap ok] (BERT a, BERT b, BERT c, BERT d) => BERT (a, b, c, d)
- Data.BERT.Term: instance [overlap ok] (Ord k, BERT k, BERT v) => BERT (Map k v)
- Data.BERT.Term: instance [overlap ok] BERT Bool
- Data.BERT.Term: instance [overlap ok] BERT ByteString
- Data.BERT.Term: instance [overlap ok] BERT Float
- Data.BERT.Term: instance [overlap ok] BERT Int
- Data.BERT.Term: instance [overlap ok] BERT Integer
- Data.BERT.Term: instance [overlap ok] BERT String
- Data.BERT.Term: instance [overlap ok] BERT Term
- Data.BERT.Term: instance [overlap ok] BERT a => BERT [a]
- Data.BERT.Term: instance [overlap ok] Binary Term
- Data.BERT.Types: instance Eq Term
- Data.BERT.Types: instance Ord Term
- Data.BERT.Types: instance Read Term
- Data.BERT.Types: instance Show Term
- Network.BERT.Client: instance Eq Error
- Network.BERT.Client: instance Ord Error
- Network.BERT.Client: instance Show Error
- Network.BERT.Server: instance Eq DispatchResult
- Network.BERT.Server: instance Ord DispatchResult
- Network.BERT.Server: instance Show DispatchResult
- Network.BERT.Transport: getTcpListenSocket :: TCPServer -> !Socket
- Network.BERT.Transport: getTcpSocket :: TCP -> !Socket
- Network.BERT.Transport: instance Server TCPServer
- Network.BERT.Transport: instance Transport TCP
+ Data.BERT.Packet: instance Data.Binary.Class.Binary Data.BERT.Packet.Packet
+ Data.BERT.Packet: instance GHC.Classes.Eq Data.BERT.Packet.Packet
+ Data.BERT.Packet: instance GHC.Classes.Ord Data.BERT.Packet.Packet
+ Data.BERT.Packet: instance GHC.Show.Show Data.BERT.Packet.Packet
+ Data.BERT.Term: instance (Data.BERT.Term.BERT a, Data.BERT.Term.BERT b) => Data.BERT.Term.BERT (a, b)
+ Data.BERT.Term: instance (Data.BERT.Term.BERT a, Data.BERT.Term.BERT b, Data.BERT.Term.BERT c) => Data.BERT.Term.BERT (a, b, c)
+ Data.BERT.Term: instance (Data.BERT.Term.BERT a, Data.BERT.Term.BERT b, Data.BERT.Term.BERT c, Data.BERT.Term.BERT d) => Data.BERT.Term.BERT (a, b, c, d)
+ Data.BERT.Term: instance (GHC.Classes.Ord k, Data.BERT.Term.BERT k, Data.BERT.Term.BERT v) => Data.BERT.Term.BERT (Data.Map.Base.Map k v)
+ Data.BERT.Term: instance Data.BERT.Term.BERT Data.BERT.Types.Term
+ Data.BERT.Term: instance Data.BERT.Term.BERT Data.ByteString.Lazy.Internal.ByteString
+ Data.BERT.Term: instance Data.BERT.Term.BERT GHC.Base.String
+ Data.BERT.Term: instance Data.BERT.Term.BERT GHC.Integer.Type.Integer
+ Data.BERT.Term: instance Data.BERT.Term.BERT GHC.Types.Bool
+ Data.BERT.Term: instance Data.BERT.Term.BERT GHC.Types.Float
+ Data.BERT.Term: instance Data.BERT.Term.BERT GHC.Types.Int
+ Data.BERT.Term: instance Data.BERT.Term.BERT a => Data.BERT.Term.BERT [a]
+ Data.BERT.Term: instance Data.Binary.Class.Binary Data.BERT.Types.Term
+ Data.BERT.Types: instance GHC.Classes.Eq Data.BERT.Types.Term
+ Data.BERT.Types: instance GHC.Classes.Ord Data.BERT.Types.Term
+ Data.BERT.Types: instance GHC.Read.Read Data.BERT.Types.Term
+ Data.BERT.Types: instance GHC.Show.Show Data.BERT.Types.Term
+ Network.BERT.Client: instance GHC.Classes.Eq Network.BERT.Client.Error
+ Network.BERT.Client: instance GHC.Classes.Ord Network.BERT.Client.Error
+ Network.BERT.Client: instance GHC.Show.Show Network.BERT.Client.Error
+ Network.BERT.Server: instance GHC.Classes.Eq Network.BERT.Server.DispatchResult
+ Network.BERT.Server: instance GHC.Classes.Ord Network.BERT.Server.DispatchResult
+ Network.BERT.Server: instance GHC.Show.Show Network.BERT.Server.DispatchResult
+ Network.BERT.Transport: [getTcpListenSocket] :: TCPServer -> !Socket
+ Network.BERT.Transport: [getTcpSocket] :: TCP -> !Socket
+ Network.BERT.Transport: instance Network.BERT.Transport.Server Network.BERT.Transport.TCPServer
+ Network.BERT.Transport: instance Network.BERT.Transport.Transport Network.BERT.Transport.TCP

Files

CHANGELOG.md view
@@ -1,3 +1,9 @@+Version 1.2.2.5+---------------++* Fix a list deserialization bug+* Serialize small ints compactly+ Version 1.2.2.4 --------------- 
bert.cabal view
@@ -1,6 +1,6 @@ cabal-version: >= 1.16 name:          bert-version:       1.2.2.4+version:       1.2.2.5 build-type:    Simple license:       BSD3 license-file:  LICENSE
src/Data/BERT/Term.hs view
@@ -177,7 +177,9 @@  -- | Binary encoding of a single term (without header) putTerm :: Term -> PutM ()-putTerm (IntTerm value) = tag 98 >> put32s value+putTerm (IntTerm value)+  | 0 <= value && value < 256 = tag 97 >> put8u value+  | otherwise                 = tag 98 >> put32s value putTerm (FloatTerm value) =   tag 99 >> (putL . C.pack . pad $ printf "%15.15e" value)   where@@ -203,7 +205,7 @@   where     len = B.length value putTerm (ListTerm value)-  | len == 0 = putNil  -- this is mentioend in the BERT spec.+  | len == 0 = putNil  -- this is mentioned in the BERT spec.   | otherwise= do       tag 108       put32u $ length value@@ -231,12 +233,19 @@     105 -> get32u >>= getN >>= tupleTerm     106 -> return $ ListTerm []     107 -> get16u >>= getL >>= return . BytelistTerm-    108 -> get32u >>= getN >>= return . ListTerm+    108 -> get32u >>= \n -> getN n <* expectNil >>= return . ListTerm     109 -> get32u >>= getL >>= return . BinaryTerm     110 -> getBigint get8u >>= return . BigintTerm . fromIntegral     111 -> getBigint get32u >>= return . BigintTerm . fromIntegral   where+    getN :: Int -> Get [Term]     getN n = replicateM n getTerm+    expectNil :: Get ()+    expectNil = do+      tag <- get8u+      case tag of+        106 -> return ()+        _   -> fail $ "invalid list - expected list ending with Nil"     -- First try & decode composite terms.     tupleTerm [AtomTerm "bert", AtomTerm "true"]  = return $ BoolTerm True     tupleTerm [AtomTerm "bert", AtomTerm "false"] = return $ BoolTerm False@@ -304,9 +313,13 @@ put32s = putWord32be . (fromIntegral :: Int32 -> Word32) . fromIntegral putL = putLazyByteString +get8u :: (Integral a) => Get a get8u  = fromIntegral <$> getWord8+get16u :: (Integral a) => Get a get16u = fromIntegral <$> getWord16be+get32u :: (Integral a) => Get a get32u = fromIntegral <$> getWord32be+get32s :: (Integral a) => Get a get32s = fromIntegral . (fromIntegral :: Word32 -> Int32) <$> getWord32be getL :: (Integral a) => a -> Get ByteString getL = getLazyByteString . fromIntegral
tests/test.hs view
@@ -1,9 +1,10 @@-{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances #-}+{-# LANGUAGE FlexibleInstances, MultiParamTypeClasses, OverloadedStrings #-}  import Control.Monad  import Data.Binary-import Data.Char (chr)+import Data.Char (chr, ord)+import Data.List (genericLength) import Data.Map (Map) import qualified Data.ByteString.Lazy as L import qualified Data.Map as Map@@ -42,16 +43,22 @@     else Left  $ printf "%s /= %s" sx sy  -- value -> Term -> encoded -> Term -> value+t :: (BERT a, Eq a, Show a) => T a t a = Right a `eqVerbose` (readBERT . decode . encode . showBERT) a+ -- value -> Term -> Packet -> encoded -> Packet -> Term -> value+p :: (BERT a, Eq a, Show a) => T a p a = Right a `eqVerbose` (readBERT . fromPacket . decode . encode . Packet . showBERT) a +main :: IO () main = defaultMain $ localOption (SmallCheckDepth 4) $   testGroup "Tests"     [ testGroup "Serialization" [simpleTerms, simplePackets]     , networkTests+    , testGroup "Specification compliance" specTests     ] +simpleTerms :: TestTree simpleTerms = testGroup "Simple terms"   [ testProperty "Bool" (t :: T Bool)   , testProperty "Integer" (t :: T Integer)@@ -64,6 +71,7 @@   , testProperty "(Int, Int, Int, Int)" (t :: T (Int, Int, Int, Int))   ] +simplePackets :: TestTree simplePackets = testGroup "Simple packets"   [ testProperty "Bool" (p :: T Bool)   , testProperty "Integer" (p :: T Integer)@@ -75,6 +83,7 @@   , testProperty "(String, Int, Int, Int)" (p :: T (String, Int, Int, Int))   ] +networkTests :: TestTree networkTests = testGroup "Network"   [ networkTest1   , networkTest2@@ -88,6 +97,7 @@ delay :: IO () delay = threadDelay (10^5) +networkTest1 :: TestTree networkTest1 = testCase "Simple call" $ do   t <- tcpServer port   let server = serve t $ \ "mod" "f" [IntTerm a] -> return $ Success $ IntTerm (a+1)@@ -97,6 +107,7 @@     result <- call c "mod" "f" [IntTerm 3]     result @?= Right (IntTerm 4) +networkTest2 :: TestTree networkTest2 = testCase "5 calls per connection" $ do   t <- tcpServer port   let server = serve t $ \ "mod" "f" [IntTerm a, IntTerm b] -> return $ Success $ IntTerm (a+b)@@ -107,6 +118,7 @@       result <- call c "mod" "f" [IntTerm 3, IntTerm x]       result @?= Right (IntTerm (3+x)) +networkTest3 :: TestTree networkTest3 = testCase "5 sequential connections" $ do   t <- tcpServer port   let server = serve t $ \ "mod" "f" [IntTerm a, IntTerm b] -> return $ Success $ IntTerm (a+b)@@ -117,6 +129,7 @@       result <- call c "mod" "f" [IntTerm 3, IntTerm x]       result @?= Right (IntTerm (3+x)) +networkTest4 :: TestTree networkTest4 = testCase "100 simultaneous connections" $ do   t <- tcpServer port   let server = serve t $ \ "mod" "f" [IntTerm a, IntTerm b] ->@@ -132,3 +145,68 @@           result <- call c "mod" "f" [IntTerm 3, IntTerm x]           result @?= Right (IntTerm (3+x))   maybe (assertFailure "Timed out!") (const $ return ()) r++ord' :: Char -> Word8+ord' = fromIntegral . ord++-- Test internal representation according to specification+-- http://erlang.org/doc/apps/erts/erl_ext_dist.html+specTests :: [TestTree]+specTests =+  [ thereAndBackAgainTest "SMAL_INTEGER_EXT" (IntTerm 5) [131, 97, 5]+  , thereAndBackAgainTest "INTEGER_EXT" (IntTerm 0x400) [131, 98, 0, 0, 4, 0]+  , thereAndBackAgainTest "ATOM_EXT"+      (AtomTerm "foobar")+      ([131, 100, 0, 6] ++ map ord' "foobar")+  , thereAndBackAgainTest "SMALL_TUPLE_EXT"+      (TupleTerm+         [ AtomTerm x+         | x <- ["a", "b", "c", "d"]+         ])+      ([131, 104, 4] +++       concat [ [100, 0, genericLength x] ++ map ord' x+              | x <- ["a", "b", "c", "d"]+              ])+  , thereAndBackAgainTest "LARGE_TUPLE_EXT"+      (TupleTerm+         [ AtomTerm [x]+         | x <- take 512 $ cycle ['a'..'z']+         ])+      ([131, 105, 0, 0, 2, 0] +++       concat [ [100, 0, 1, ord' x]+              | x <- take 512 $ cycle ['a'..'z']+              ])+  , thereAndBackAgainTest "NIL_EXT"+      (ListTerm [])+      [131, 106]+  , thereAndBackAgainTest "STRING_EXT"+      (BytelistTerm "abc\0")+      [131, 107, 0, 4, 97, 98, 99, 0]+  , thereAndBackAgainTest "LIST_EXT"+      (ListTerm [AtomTerm "abc", AtomTerm "xyz"])+      ([131, 108, 0, 0, 0, 2] +++       [100, 0, 3, 97, 98, 99] +++       [100, 0, 3, 120, 121, 122] +++       [106])+  , thereAndBackAgainTest "LIST_EXT - nested"+      (ListTerm [ListTerm [AtomTerm "abc"], ListTerm [AtomTerm "xyz"]])+      ([131, 108, 0, 0, 0, 2] +++       ([108, 0, 0, 0, 1] ++ [100, 0, 3, 97, 98, 99]    ++ [106]) +++       ([108, 0, 0, 0, 1] ++ [100, 0, 3, 120, 121, 122] ++ [106]) +++       [106])+  , thereAndBackAgainTest "BINARY_EXT"+      (BinaryTerm "x\0y\1z")+      ([131, 109, 0, 0, 0, 5, 120, 0, 121, 1, 122])+  , thereAndBackAgainTest " SMALL_BIG_EXT"+      (BigintTerm $ 4 + 3 * 256 + 2 * 256^2 + 1 * 256^3)+      ([131, 110, 4, 0, 4, 3, 2, 1])+  ]++thereAndBackAgainTest :: String -> Term -> [Word8] -> TestTree+thereAndBackAgainTest name term binaryRepr = testGroup name+  [ testCase "Term -> binary" $+      L.unpack (encode term) @?= binaryRepr+  , testCase "binary -> Term" $+      decode (L.pack binaryRepr) @?= term+  ]+